﻿using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
using O1.Kernel.Storage.Transactions;

namespace O1.Kernel.Primitives
{
    [StructLayout(LayoutKind.Explicit)]
    internal struct VertexHead
    {
        public const int Size = Tx.Size + Sz.Cell.CellAddress;

        [FieldOffset(0)]
        public readonly Tx TxHeader;

        [FieldOffset(Tx.Size)]
        public readonly CellAddress NextShardAddress;

        public VertexHead(Tx txHeader, CellAddress nextShardAddress)
            : this()
        {
            this.TxHeader = txHeader;
            this.NextShardAddress = nextShardAddress;
        }

        public VertexHead(Tx txHeader)
            : this()
        {
            this.TxHeader = txHeader;
        }

        internal static unsafe VertexHead Read(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                return *(VertexHead*)p;
            }
        }

        internal unsafe void Write(byte[] buffer, int offset)
        {
            Contract.Requires(buffer != null);
            Contract.Requires(0 <= offset);
            Contract.Requires(offset + Size < buffer.Length, ExceptionText.ValueBufferTooSmall);

            fixed (byte* p = &buffer[offset])
            {
                *((VertexHead*)p) = this;
            }
        }
    }
}